package com.design.stack;

import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * @author cxx
 * @create 2020-04-20 13:33
 **/
public class Main {

    /**
     * 先进后出弹栈模式
     * @param args
     */
    public static void main(String[] args) {

        List<Filter> all = new ArrayList<> ();
        all.add (new FirstFilter ());
        all.add (new TwoFilter ());
        all.add (new ThreeFilter ());

        FilterContainer filterContainer = new FilterContainer (all,new Request (),new Response ());

        doMainFilter (filterContainer);

    }

    static class FilterContainer{

        private List<Filter> filters;

        private Deque<Filter> deque;

        private Request request;

        private Response response;

        public FilterContainer(List<Filter> filters,Request request,Response response) {

            this.filters = filters;
            this.deque = new LinkedBlockingDeque<> ();
            deque.add (filters.get (0));
            this.request = request;
            this.response = response;
        }

        public List<Filter> getFilters() {
            return filters;
        }

        public Deque<Filter> getDeque() {
            return deque;
        }

        public Request getRequest() {
            return request;
        }

        public Response getResponse() {
            return response;
        }
    }


    private static void doMainFilter(FilterContainer filterContainer){
        Filter filter = filterContainer.getDeque ().getLast ();
        filter.doFilter (filterContainer.getRequest (), filterContainer.getResponse (), new FilterChain () {
            @Override
            public void doFilter(Request request, Response response) {
                Filter last = filter;
                int index = filterContainer.getFilters ().indexOf (last);
                if(index == filterContainer.getFilters ().size () - 1){
                    doService(request,response);
                    return;
                }
                Filter nextFilter = filterContainer.getFilters ().get (++index);
                filterContainer.getDeque ().add (nextFilter);
                doMainFilter (filterContainer);
            }
        });
    }

    private static void doService(Request request,Response response){
        System.out.println (request.hashCode () + ":::" + response.hashCode ());
    }

}
